查看原文
其他

Android逆向之smali

达达 Th0r安全 2023-10-31

点击蓝字 · 关注我们

前言

Smali是Android虚拟机的反汇编语言。在安卓逆向中是非常重要的,就类似于汇编语言。本篇文章给大家带来关于Smali的基本语法和远程动态调试。在接触的时候,如果有JVM字节码基础,会发现两者还是有相似的地方。

这里推荐一个AS的插件,java2smali,可以将java代码转换为smali,可以让人更好的实践理解smali.


JAVA的类型与smali描述

  java 类型  smail 描述符

  boolean      Z

  byte            B

  short           S

  char            C

  int                I

  long            J

  float            F

  double        D

  void            V

 数组             L

 对象            [../../


返回关键字

smali方法返回关键字和其后面可以跟的数据类型

 return           byte

 return           short

 return           int

 return           char

 return           boolean

 return           float

 return-wide  double

 return-wide   long

 return-void    void

 return-object   数组

 return-object   object



异常指令

throw

数据转换指令

int-to-long       整型转为长整型

float-to-int      单精度浮点型转为整型

int-tobyte       整型转为字节类型

neg-int          求补指令,对整数求补

not-int            求反指令,对整数求反



比较指令

cmpl-类型   VC,VA,VB,比较VA,VB较小值

cmpg-类型   VC,VA,VB 比较VA,VB较大值


数据定义指令

const-string       字符串值

const-class        字节码对象赋值

const/4             最大存放4位数值(-8到7)

const/16            最大存放16位数值(-32768到32767)

const                 最大存放32位数值

const/high16     只存放高16位数值

const-wide          最大存放64位数值

const-wide/16     最大存放16位数值

const-wide/32      最大存放32位数值

const-wide/high16  只存放高16位数值



变量操作指令

move v1,v2           

将v2中的值移入到v1寄存器中(4位,支持int型)

 move/from16 v1,v2 

 将16位的v2寄存器中的值移入到8位的v1寄存器这

 move/16     v1,v2      

将16位的v2寄存器中的值移入到16位的v1寄存器中

move-wide  v1,v2    

将16位的v2寄存器中的值移入到v1寄存器对中

move-wide/from16 v1,v2   

将16位的v2寄存器(一组)中的值移入到8位的v1寄存器在中

move-wide/16  v1,v2      

将16位的v2寄存器(一组)中的值移入到16位的v1寄存器中

move-object     v1,v2       

将v2中的对象指针移入到v1寄存器中

move-object  v1,v2          

将v2中的对象指针移入到v1寄存器中

move-object/from16 v1,v2  

将16位的v2寄存器中的对象指针移入到v1(8位)寄存器中

move-object/16 v1,v2    

将16位的v2寄存器中的对象指针移入到v1(16位)寄存器中

move-result v1    

将这个指令的上一条指令计算结果,移入到v1寄存器中(需要配合invoke-staic、invoke-virtual等指令使用)

move-result-object v1   

将上条计算结果的对象指针移入v1寄存器

move-result-wide   

v1将上条计算结果(双字)的对象指针移入v1寄存器

move-exception     

v1   将异常移入v1寄存器,用于捕获try-catch语句中的异常



 条件跳转指令

if-eq vA,vB,:cond_   如果vA等于vB,则跳转

if-ne   vA,vB, :cond_   如果vA不等于vB,则跳转

if-lt    vA,vB, :cond_    如果vA小于vB,则跳转

if-le    vA,vB, :cond_    如果vA小于等于vB,则跳转

if-gt      vA,vB, :cond_   如果vA大于vB,则跳转

if-ge      vA,vB, :cond_   如果vA大于等于vb,则跳转

if-eqz    vA,:cond_           如果vA等于0,则跳转

if-nez    vA,:cond_            如果vA不等于0,在跳转

if-ltz      vA,:cond_        如果vA小于0,则跳转

if-lez      vA,:cond_       如果vA小于等于0,则跳转

if-gtz      vA,:cond_      如果vA大于0,则跳转

if-gez     vA,:cond_      如果vA大于等于0,则跳转



Smali关键词

.class     包名+类名

.super    父类类名

.source   源文件名称

.implements  接口实现

.field       定义变量

.method/.end method   方法的开始与结束

.locals  方法内使用的v开头的寄存器个数

.prologue   表示方法中代码的开始处

.line   对于java中的行数

.paramter/.param  指定的方法参数

.annotation./end annotation  注解的开始和结束

.registers 表示该方法使用到的寄存器的个数

.local   表示方法中非参数的变量

.cond_N     条件分支,配合if使用

.goto_N    goto跳转标记

寄存器

v变量表示方法中非参数变量

p变量表示方法中参数变量

方法调用指令

 invoke-direct    调用私有方法和构造方法

 invoke-virtual  调用普通的实例方法,(被public,protected或没有修饰符的方法)

 invoke-static     调用静态方法

 invoke-super    调用父类方法

 invoke-interface      调用接口中的方法


利用插件实操

这里我们用java2smali这个插件进行实际操作。


从这里可以我们可以得到它是com/example/first/包中的,继承的父类是androidx/appcompat/app/AppCompatActivity,名字是MainActivity.java


从这里我们可以看出这一段是变量定义,可以从中得出它的变量名,访问修饰符,类型。


这里看到这是一段init方法,可以看出它用到的寄存器个数,调用的方法和返回值的类型。

Smali远程调试

这里用到的工具:

夜神模拟器

adb

smalidea

monitor.exe

夜神模拟器和adb就不说了,主要讲一下smalidea和monitor.exe还有调试步骤。

smalidea,这里之前直接用的网上教程0.05版本的,但是用了之后报错,所以换成了0.06的,这里踩了一个坑。

monitor.exe是自带的,但是使用的时候要注意系统架构的适配。

这里一般存放的路径是在SDK里的tools下的lib.会发现有两个文件夹,选一个适合自己机子的。


接下来用的案例是教我兄弟学android逆向的文件。

这里输入下面这个命令

adb shell am start -D -n hfdcxy.com.myapplication/hfdcxy.com.myapplication.MainActivity


可以看到monitor已经监控到了


这里需要注意到3111这个(每次都会不一样),下面的命令需要用到。


这里再用adb forward tcp:8700 jdwp:3111,

3111这一部分,则需要根据情况修改。在用这个命令的适合要先关掉monitor,不然会报错。


这里再把从网上下载到的smalidea插件放到plugins目录下。然后File->settings->plugins,然后再点击如下图的地方。


这里还要再修改Editor->File Types。移掉smali support的*.smali.把smalidea中添加*.smali.


接下来把smali导入到AS中。


再配置一下JDK


现在就可以开始愉快的debug了。


继续滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存